package organizer.hb;

import java.util.Iterator;
import java.util.List;
import organizer.IFileMetadata;
import organizer.MetadataComparator;

/**
 * Generic implementation of a metadata list.
 * Iterates a collection of metadata by chunks.
 * @author dawong
 */
public class MetadataList implements Iterable<IFileMetadata> {
    
    private MetadataDao metadataDao;

    public MetadataList(MetadataDao metadataDao) {
        this.metadataDao = metadataDao;
    }
    
    public void clear() {
        metadataDao.clear();
    }
    
    public void add(IFileMetadata meta) {
        metadataDao.add(meta);
    }

    public void sort(MetadataComparator comp) {
        metadataDao.sort(comp);
    }

    public int size() {
        return metadataDao.size();
    }

    public Iterator<IFileMetadata> iterator() {
        return new Iterator<IFileMetadata>() {
            
            int index = 0;
            int size = metadataDao.size();
            List<IFileMetadata> subList;
            int subIndex = 0;

            public boolean hasNext() {
                return index < size;
            }

            public IFileMetadata next() {
                if (subList == null || subIndex == subList.size()) {
                    subList = metadataDao.getSorted(index, 1000);
                    subIndex = 0;
                }
                index++;
                return subList.get(subIndex++);
            }

            public void remove() {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        };
    }

    public int getNumberOfSameLengthFiles() {
        return metadataDao.getNumberOfSameLengthFiles();
    }

    public List<Long> getLengthGroups() {
        return metadataDao.getLengthGroups();
    }

    public Iterator<IFileMetadata> getFilesOfLength(final long length) {
        return new Iterator<IFileMetadata>() {
            
            int index = 0;
            int size = metadataDao.getNumberOfFilesOfLength(length);
            List<IFileMetadata> subList;
            int subIndex = 0;

            public boolean hasNext() {
                return index < size;
            }

            public IFileMetadata next() {
                if (subList == null || subIndex == subList.size()) {
                    subList = metadataDao.getFilesOfLength(length, index, 1000);
                    subIndex = 0;
                }
                index++;
                return subList.get(subIndex++);
            }

            public void remove() {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        };
    }

    public List<IFileMetadata> getFilesOfHash(String hash) {
        return metadataDao.getFilesOfHash(hash);
    }

}
